/**
 * 简化错误处理
 * 专注于内容分发平台的核心需求
 */

import { ErrorCode } from '../types/core';

/**
 * ContentFlow 基础错误类
 */
export class ContentFlowError extends Error {
  public readonly code: ErrorCode;
  public readonly details?: any;
  public readonly timestamp: Date;

  constructor(
    message: string,
    code: ErrorCode = ErrorCode.UNKNOWN_ERROR,
    details?: any
  ) {
    super(message);
    this.name = this.constructor.name;
    this.code = code;
    this.details = details;
    this.timestamp = new Date();

    // 捕获错误堆栈信息
    if (Error.captureStackTrace) {
      Error.captureStackTrace(this, this.constructor);
    }
  }

  /**
   * 转换为错误详情对象
   */
  toErrorDetails() {
    return {
      code: this.code,
      message: this.message,
      details: this.details,
      timestamp: this.timestamp,
      stack: this.stack
    };
  }
}

/**
 * 存储相关错误
 */
export class StorageError extends ContentFlowError {
  constructor(message: string, details?: any) {
    super(message, ErrorCode.STORAGE_ERROR, details);
  }
}

/**
 * 平台相关错误
 */
export class PlatformError extends ContentFlowError {
  constructor(message: string, details?: any) {
    super(message, ErrorCode.PLATFORM_ERROR, details);
  }
}

/**
 * API 相关错误
 */
export class APIError extends ContentFlowError {
  constructor(message: string, details?: any) {
    super(message, ErrorCode.API_ERROR, details);
  }
}

/**
 * 账号相关错误
 */
export class AccountError extends ContentFlowError {
  constructor(message: string, details?: any) {
    super(message, ErrorCode.ACCOUNT_ERROR, details);
  }
}

/**
 * 频率限制错误
 */
export class RateLimitError extends ContentFlowError {
  constructor(message: string, details?: any) {
    super(message, ErrorCode.RATE_LIMIT_ERROR, details);
  }
}

/**
 * 验证错误
 */
export class ValidationError extends ContentFlowError {
  constructor(message: string, details?: any) {
    super(message, ErrorCode.VALIDATION_ERROR, details);
  }
}

/**
 * 网络错误
 */
export class NetworkError extends ContentFlowError {
  constructor(message: string, details?: any) {
    super(message, ErrorCode.NETWORK_ERROR, details);
  }
}

/**
 * 初始化错误
 */
export class InitializationError extends ContentFlowError {
  constructor(message: string, details?: any) {
    super(message, ErrorCode.INITIALIZATION_ERROR, details);
  }
}

/**
 * 错误工厂函数
 */
export function createError(
  code: ErrorCode,
  message: string,
  details?: any
): ContentFlowError {
  switch (code) {
    case ErrorCode.STORAGE_ERROR:
      return new StorageError(message, details);
    case ErrorCode.PLATFORM_ERROR:
      return new PlatformError(message, details);
    case ErrorCode.API_ERROR:
      return new APIError(message, details);
    case ErrorCode.ACCOUNT_ERROR:
      return new AccountError(message, details);
    case ErrorCode.RATE_LIMIT_ERROR:
      return new RateLimitError(message, details);
    case ErrorCode.VALIDATION_ERROR:
      return new ValidationError(message, details);
    case ErrorCode.NETWORK_ERROR:
      return new NetworkError(message, details);
    case ErrorCode.INITIALIZATION_ERROR:
      return new InitializationError(message, details);
    default:
      return new ContentFlowError(message, code, details);
  }
}

/**
 * 错误处理装饰器
 */
export function handleErrors(_target: any, _propertyKey: string, descriptor: PropertyDescriptor) {
  const originalMethod = descriptor.value;

  descriptor.value = async function (...args: any[]) {
    try {
      return await originalMethod.apply(this, args);
    } catch (error) {
      if (error instanceof ContentFlowError) {
        throw error;
      }
      
      // 将普通错误转换为 ContentFlowError
      throw new ContentFlowError(
        error instanceof Error ? error.message : String(error),
        ErrorCode.UNKNOWN_ERROR,
        { originalError: error }
      );
    }
  };

  return descriptor;
}

/**
 * 重试装饰器
 */
export function retry(maxRetries: number = 3, delay: number = 1000) {
  return function (_target: any, _propertyKey: string, descriptor: PropertyDescriptor) {
    const originalMethod = descriptor.value;

    descriptor.value = async function (...args: any[]) {
      let lastError: Error;

      for (let attempt = 0; attempt <= maxRetries; attempt++) {
        try {
          return await originalMethod.apply(this, args);
        } catch (error) {
          lastError = error as Error;
          
          if (attempt < maxRetries) {
            await new Promise(resolve => setTimeout(resolve, delay));
          }
        }
      }

      throw lastError!;
    };

    return descriptor;
  };
}
